
package com.smvc.aspects;
import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import com.smvc.annotations.MyLog;

@Aspect
@Component("logAspect")
public class LogAspect {

	private static final Logger log = Logger.getLogger(LogAspect.class);

	// 配置织入点
	@Pointcut("@annotation(com.smvc.annotations.MyLog)")
	public void logPointCut() {
	}

	/**
	 * 前置通知 用于拦截操作，在方法返回后执行
	 * 
	 * @param joinPoint
	 *            切点
	 */
	@AfterReturning(pointcut = "logPointCut()")
	public void doBefore(JoinPoint joinPoint) {
		handleLog(joinPoint, null);
	}

	/**
	 * 拦截异常操作，有异常时执行
	 * 
	 * @param joinPoint
	 * @param e
	 */
	@AfterThrowing(value = "logPointCut()", throwing = "e")
	public void doAfter(JoinPoint joinPoint, Exception e) {
		handleLog(joinPoint, e);
	}

	private void handleLog(JoinPoint joinPoint, Exception e) {
		try {
			// 获得注解
			MyLog controllerLog = getAnnotationLog(joinPoint);
			if (controllerLog == null) {
				return;
			}
			// 获得方法名称
			String className = joinPoint.getTarget().getClass().getName();
			String methodName = joinPoint.getSignature().getName();
			String action = controllerLog.operate();
			// 打印日志，如有需要还可以存入数据库
			log.info("类名"+className);
		} catch (Exception exp) {
			exp.printStackTrace();
		}
	}

	/**
	 * 是否存在注解，如果存在就获取
	 */
	private static MyLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
		Signature signature = joinPoint.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();
		if (method != null) {
			return method.getAnnotation(MyLog.class);
		}
		return null;
	}
}